#include <iostream>
#include <algorithm>
#include <vector>
#include <deque>

int const maxn = 102;
bool vis[maxn];
bool vis_edge[maxn][maxn];
int indegree[maxn];
int color[maxn][maxn];
int n, m;

typedef std::vector<int> edge_type;
typedef edge_type::iterator edge_it;
std::vector<edge_type> graph;

int dfs(int x)
{
	vis[x] = true;
	int sum = (indegree[x]&1);
	for (edge_it it = graph[x].begin(); it != graph[x].end(); ++it) {
		int v = *it;
		if (vis[v]) continue;
		sum += dfs(v);
		if (sum > 2) return sum;
	}
	return sum;
}

bool eulerian_tour_odd_path(int x, int co) // 1: white  0: black
{
	for (edge_it it = graph[x].begin(); it != graph[x].end(); ++it) {
		int v = *it;
		if (vis_edge[x][v]) continue;
		vis_edge[x][v] = vis_edge[v][x] = true;
		color[x][v] = color[v][x] = co;
		indegree[x]--; indegree[v]--;
		if (eulerian_tour_odd_path(v, 1 - co)) return true;
	}
	return true;
}

std::deque<int> euler_tour;
void eulerian_tour(int x)
{
	for (edge_it it = graph[x].begin(); it != graph[x].end(); ++it) {
		int v = *it;
		if (vis_edge[x][v]) continue;
		vis_edge[x][v] = vis_edge[v][x] = true;
		indegree[x]--; indegree[v]--;
		eulerian_tour(v);
	}
	euler_tour.push_back(x);
}

void color_euler_tour()
{
	for (int i = 1, co = 1; i < (int)euler_tour.size(); i++) {
		int u = euler_tour[i - 1], v = euler_tour[i];
		color[u][v] = color[v][u] = co;
		co = 1 - co;
	}
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin >> n >> m;
	graph.resize(n);
	for (int i = 0, x, y; i < m; i++) {
		std::cin >> x >> y;
		x--; y--;
		graph[x].push_back(y);
		graph[y].push_back(x);
		indegree[x]++; indegree[y]++;
	}

	for (int i = 0; i < n; i++)
		if (indegree[i] & 1) {
			std::fill(vis, vis + n, 0);
			int odd_degree = dfs(i);
			if (odd_degree == 2) {
				euler_tour.clear();
				eulerian_tour(i);
				color_euler_tour();
			} else {
				eulerian_tour_odd_path(i, 1);
			}
		}

	for (int i = 0; i < n; i++)
		if (indegree[i]) {
			euler_tour.clear();
			eulerian_tour(i);

			for (int count = euler_tour.size(); count
					&& graph[euler_tour[0]].size() <= 2; count--) {
				euler_tour.pop_front();
				euler_tour.push_back(euler_tour[0]);
			}
			color_euler_tour();
		}


	// No solution
	for (int i = 0; i < n; i++) {
		bool black = false, white = false;
		if (graph[i].size() <= 1) continue;
		for (edge_type::iterator it = graph[i].begin(); it != graph[i].end(); ++it) {
			int v = *it;
			if (color[i][v] == 1) white = true;
			else
			if (color[i][v] == 2) black = true;
		}
		if (!(white && black)) {
			std::cout << "No solution\n";
			return 0;
		}
	}

	for (int i = 0; i < n; i++) {
		for (edge_type::iterator it = graph[i].begin(); it != graph[i].end(); ++it) {
			int v = *it;
			std::cout << color[i][v] << ' ';
		}
		std::cout << "0\n";
	}
}

